package com.auth.gateway.filter;

import com.auth.gateway.model.LoginSession;
import com.auth.gateway.model.SystemLoginConfig;
import com.auth.gateway.service.LoginStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@Component
public class AuthInjectionFilter implements GlobalFilter, Ordered {

    @Autowired
    private Map<String, LoginStrategy> strategies;

    private final Map<String, LoginSession> sessionCache = new ConcurrentHashMap<>();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String path = exchange.getRequest().getPath().toString();
        String systemCode = extractSystemCode(path); // 例如 legacy-a
        String userId = getCurrentUser(exchange);    // 从 JWT/CAS 获取

        LoginSession session = sessionCache.get(userId + ":" + systemCode);

        Mono<LoginSession> sessionMono = session != null
                ? Mono.just(session)
                : loginForSystem(userId, systemCode).doOnNext(s -> sessionCache.put(userId + ":" + systemCode, s));

        return sessionMono.flatMap(s -> {
            ServerHttpRequest.Builder mutated = exchange.getRequest().mutate();
            s.getHeaders().forEach(mutated::header);
            if (!s.getCookies().isEmpty()) {
                String cookieHeader = s.getCookies().entrySet().stream()
                        .map(e -> e.getKey() + "=" + e.getValue())
                        .collect(Collectors.joining("; "));
                mutated.header(HttpHeaders.COOKIE, cookieHeader);
            }
            return chain.filter(exchange.mutate().request(mutated.build()).build());
        });
    }

    private Mono<LoginSession> loginForSystem(String userId, String systemCode) {
        SystemLoginConfig config = loadConfig(systemCode);
        LoginStrategy strategy = strategies.get(config.getLoginType().name().toLowerCase() + "LoginStrategy");
        return strategy.login(userId, config);
    }

    @Override
    public int getOrder() {
        return -10;
    }

    /**
     * 加载当前系统的登录配置（依赖 SystemLoginProperties）
     * @param systemCode
     * @return
     */
    public SystemLoginConfig loadConfig(String systemCode) {
        return new SystemLoginConfig();
    }
    /**
     * 从请求路径中提取系统标识（如 /legacy-a/** → legacy-a）
     * @param path
     * @return
     */
    private String extractSystemCode(String path) {
        // 假设路径格式为 /{systemCode}/rest/of/path
        if (path == null || path.isEmpty()) return null;
        String[] segments = path.split("/");
        return segments.length > 1 ? segments[1] : null;
    }

    /**
     * 从请求头中提取 统一身份认证的 当前用户
     * @param exchange
     * @return
     */
    private String getCurrentUser(ServerWebExchange exchange) {
        List<String> authHeaders = exchange.getRequest().getHeaders().get(HttpHeaders.AUTHORIZATION);
        if (authHeaders == null || authHeaders.isEmpty()) {
            return null;
        }
        String authHeader = authHeaders.get(0);
        if (!authHeader.startsWith("Bearer ")) {
            return null;
        }
        String token = authHeader.substring(7);
        try {

            return "";  // or claims.get("username", String.class)
        } catch (Exception e) {
            return null;
        }
    }
}